package NG::Sys::Cached::DBRowName;
use strict;
use warnings;
use utf8;

use base 'NG::Sys::Cached::DBRow';

sub init {
	my ($self) = @_;
	$self->SUPER::init;
	unless($self->{nkey}){
		die "need nkey\n";
	}
	$self->{sth}{read_n} = $self->{dbh}->prepare("select `$self->{pkey}`,`$self->{nkey}` from `$self->{table}` where `$self->{nkey}`=?");
}
sub _remove_source {
	my ($self,$id) = @_;
	my $data = $self->_read_data($id,1);
	if($data){
		my $id_key = "{".$id."}";
		my $n_key = "[".$data->{$self->{nkey}}."]";
		$self->{cache}->remove($n_key);
		$self->{cache}->remove($id_key);
	}
	$self->SUPER::_remove_source($id);
}
sub _read_source {
	my ($self,$id) = @_;
	my $data = $self->SUPER::_read_source($id);
	if($data){
		my $id_key = "{".$id."}";
		my $n_key = "[".$data->{$self->{nkey}}."]";
		$self->{cache}->set($n_key,$id);
		$self->{cache}->set($id_key,$n_key);
	}
	return $data;
}
sub _update_source {
	unshift @_,'SUPER::_update_source';
	goto &__store_source;
}
sub _replace_source {
	unshift @_,'SUPER::_replace_source';
	goto &__store_source;
}
sub __store_source {
	my ($method,$self,$id,$data,$keys) = @_;
	my $nkeys;
	if($nkeys = $self->$method($id,$data,$keys)){
		my $n = $self->{nkey};
		if(grep {$n eq $_} @$keys){
			my $id_key = "{".$id."}";
			my $n_key = "[".$data->{$n}."]";
			$self->{cache}->set($n_key,$id);
			if(my $old = $self->{cache}->get($id_key)){
				$self->{cache}->remove($old);
			}
			$self->{cache}->set($id_key,$n_key);
		}
	}
	return $nkeys;
}
sub search_name {
	my ($self) = @_;
	return $self->{nkey};
}
sub get_by_name {
	my ($self,$name,@rest) = @_;
	my $id;
	unless($id = $self->{cache}->get("[".$name."]")){
		$self->count_action("name_source");
		my $sth = $self->{sth}{read_n};
		$sth->execute($name);
		for my $row(@{$sth->fetchall_arrayref}){
			if($row->[1] eq $name){
				$id = $row->[0];
				my $id_key = "{".$id."}";
				my $n_key = "[".$name."]";
				$self->{cache}->set($n_key,$id);
				$self->{cache}->set($id_key,$n_key);
				last;
			}
		}
	}else{
		$self->count_action("name_cache");
	}
	if($id){
		return $self->get_obj($id,@rest);
	}else{
		return undef;
	}
}
sub check_for_name {
	my ($self,$name) = @_;
	$self->count_action("name_check");
	if($self->{cache}->get("[".$name."]")){
		return 1;
	}
	my $sth = $self->{sth}{read_n};
	$sth->execute($name);
	my $row = $sth->fetchall_arrayref;
	return @$row ? 1 : 0;
}
sub clear_cache {
	my ($self,$id) = @_;
	if(my $name = $self->{cache}->get("{".$id."}")){
		$self->{cache}->remove($name);
	}
	$self->{cache}->remove("{".$id."}");
	$self->SUPER::clear_cache($id);
}

1;
